<link rel="import" href="../polymer/polymer.html">

<!--
`sign-here` provides smooth signature drawing with HTML5 Canvas by wrapping
the [signature_pad](https://github.com/szimek/signature_pad) library.

@demo demo/index.html
-->

<script src="./signature_pad/signature_pad.min.js"></script>

<dom-module id="sign-here">
  <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <canvas id="canvas"></canvas>
  </template>

  <script>
    Polymer({

      is: 'sign-here',

      properties: {
        /**
         * Width of the signature pad in pixels
         */
        width: Number,

        /**
         * Height of the signature pad in pixels
         */
        height: Number,

        /**
         * Radius of a single dot
         */
        dotSize: {
          type: Number,
          observer: '_dotSizeChanged'
        },

        /**
         * Minimum width of a line. Defaults to 0.5
         */
        minWidth: {
          type: Number,
          observer: '_minWidthChanged'
        },

        /**
         * Maximum width of a line. Defaults to 2.5
         */
        maxWidth: {
          type: Number,
          observer: '_maxWidthChanged'
        },

        /**
         * Color used to clear the background.
         * Can be any color format accepted by context.fillStyle.
         * Defaults to "rgba(0,0,0,0)" (transparent black).
         * Use a non-transparent color e.g. "rgb(255,255,255)" (opaque white)
         * if you'd like to save signatures as JPEG images.
         */
        backgroundColor: {
          type: String,
          value: 'rgb(255, 255, 255)',
          observer: '_backgroundColorChanged'
        },

        /**
         * Color used to draw the lines.
         * Can be any color format accepted by context.fillStyle.
         * Defaults to "black".
         */
        penColor: {
          type: String,
          value: 'rgb(0, 0, 0)',
          observer: '_penColorChanged'
        },

        /**
         * Weight used to modify new velocity based on the previous velocity. Defaults to 0.7
         */
        velocityFilterWeight: {
          type: Number,
          observer: '_velocityFilterWeightChanged'
        },

        /**
         * toDataUrl encoding format
         */
        type: {
          type: String,
          value: 'image/png'
        },

        /**
         * toDataUrl encoding image quality between 0 and 1
         */
        encoderOptions: {
          type: Number,
          value: 0.85
        },

        /**
         * Data uri encoded image data
         */
        image: {
          type: String,
          notify: true
        },

        /**
         * Indicates if the signature pad is currently active
         */
        active: {
          type: Boolean,
          notify: true,
          readOnly: true
        },

        /**
         * Indicates if the signature pad is empty
         */
        empty: {
          type: Boolean,
          notify: true,
          readOnly: true
        }
      },

      observers: [
        '_onEncodingChanged(type, encoderOptions)'
      ],

      ready: function() {
        var ratio =  Math.max(window.devicePixelRatio || 1, 1);

        this.$.canvas.style.width = this.width + 'px';
        this.$.canvas.style.height = this.height + 'px';
        this.$.canvas.width = this.width * ratio;
        this.$.canvas.height = this.height * ratio;
        this.$.canvas.getContext("2d").scale(ratio, ratio);

        this.signaturePad = new SignaturePad(this.$.canvas, {
          dotSize: this.dotSize,
          minWidth: this.minWidth,
          maxWidth: this.maxWidth,
          backgroundColor: this.backgroundColor,
          penColor: this.penColor,
          velocityFilterWeight: this.velocityFilterWeight,
          onBegin: this._onBegin.bind(this),
          onEnd: this._onEnd.bind(this)
        });

        this.signaturePad.clear();

        if (this.image) {
          this.signaturePad.fromDataURL(this.image);
        }

        this._setEmpty(this.signaturePad.isEmpty());
      },

      attached: function() {
        this.signaturePad.on();
      },

      detached: function() {
        this.signaturePad.off();
      },

      /**
       * Clears the image
       */
      clear: function() {
        this.signaturePad.clear();
        this.encodeImage();
      },

      /**
       * Encodes the image using the type and encodingOptions (quality) defined.
       * The encoded image is available in the `image` property.
       */
      encodeImage: function() {
        this.image = this.$.canvas.toDataURL(this.type, this.encodingOptions);
        this._setEmpty(this.signaturePad.isEmpty());
      },

      _onBegin: function(event) {
        this._setActive(true);
      },

      _onEnd: function(event) {
        this._setActive(false);
        this.encodeImage();
      },

      _dotSizeChanged: function(newValue, oldValue) {
        if (!this.signaturePad) return;
        this.signaturePad.dotSize = newValue;
      },

      _minWidthChanged: function(newValue, oldValue) {
        if (!this.signaturePad) return;
        this.signaturePad.minWidth = newValue;
      },

      _maxWidthChanged: function(newValue, oldValue) {
        if (!this.signaturePad) return;
        this.signaturePad.maxWidth = newValue;
      },

      _backgroundColorChanged: function(newValue, oldValue) {
        if (!this.signaturePad) return;
        this.signaturePad.backgroundColor = newValue;
      },

      _penColorChanged: function(newValue, oldValue) {
        if (!this.signaturePad) return;
        this.signaturePad.penColor = newValue;
      },

      _velocityFilterWeightChanged: function(newValue, oldValue) {
        if (!this.signaturePad) return;
        this.signaturePad.velocityFilterWeight = newValue;
      },

      _onEncodingChanged: function(type, encoderOptions) {
        if (this.signaturePad) {
          this.encodeImage();
        }
      }
    });
  </script>
</dom-module>
